xAPI + AI Integration Summary
-----------------------------
Original file: untitled folder 16.zip
Base mode: quiz
AI used: yes
AI provider: gemini
AI model: gemini-2.5-flash
AI status: success

Custom Instructions:
track each question asked, find the question facility

AI Explanation:
This JavaScript snippet is an immediately-invoked function expression (IIFE) to encapsulate its logic and avoid polluting the global scope. It is designed to track user interactions with an interactive canvas element and play/pause controls, then dispatch these events as "state payloads" to a `window.storeState` function, adhering strictly to the provided SLS data contract and constraints.

1.  **`_trackingState` Object**: This object holds the internal state of the tracking script, including the `sessionStartTime`, boolean flags for `isMediaPlaying` and `isCanvasDrawing`, `lastCanvasInteractionTime` for event throttling, and crucially, a `history` array which accumulates all tracked events.
2.  **`getTimeSinceStart()`**: A utility function that calculates the elapsed time in seconds since the `_trackingState.sessionStartTime`. This value populates the `t` property of each `history` event.
3.  **`sendState(historyEventPayload)` Function**: This is the central mechanism for sending data.
    *   It first pushes the `historyEventPayload` (the details of the current interaction) into the `_trackingState.history` array. Each event includes `t: getTimeSinceStart()` and `q: null` (as per "question facility" instruction).
    *   It then constructs the complete `payload` object, setting `score`, `max`, `feedback`, `reason`, and `quiz` to `null` or `0` because the detected content has no questions or scoring.
    *   The `history` property of the `payload` is set to the entire `_trackingState.history` array, representing the cumulative events.
    *   It attempts to call `window.storeState(payload)`.
    *   **Retry Mechanism**: If `window.storeState` is not yet available, the script retries calling it up to `SEND_MAX_RETRIES` times with `SEND_RETRY_INTERVAL_MS` delay. During retries, `sendState(null)` is called to prevent adding duplicate events to `_trackingState.history`.
    *   Error handling for `window.storeState` is included with `try-catch` blocks.
4.  **`initializeTracking()` Function**: This is the main setup function, called once the DOM is ready.
    *   **Initial Event**: It immediately sends an `initialized` event to mark the content load.
    *   **Page Unload Event**: It attaches an `beforeunload` listener to the `window` to send a `terminated` event when the user leaves the page, providing a completion timestamp.
    *   **Canvas Tracking**:
        *   It queries for a `canvas` element. If found, it attaches `mousedown`, `mousemove`, `mouseup`, and `mouseout` event listeners.
        *   `mousedown` triggers a `start_interaction` event.
        *   `mousemove` triggers a `drag` event, but it is **throttled** using `CANVAS_THROTTLE_THRESHOLD_MS` to prevent excessive events during continuous mouse movement.
        *   `mouseup` triggers an `end_interaction` event.
        *   `mouseout` triggers a `drawing_interrupted_mouseout` event if the user was drawing and moved the mouse off the canvas.
        *   Coordinates (`e.offsetX`, `e.offsetY`) are captured for interaction events.
    *   **Play/Pause Tracking**:
        *   It queries for elements that could function as play/pause buttons, looking for common `data-tracking-role` attributes, class names (`.play-button`, `.pause-button`), or IDs (`#playButton`, `#pauseButton`).
        *   It attaches `click` listeners to these buttons to send `media_play` and `media_pause` events, updating the `_trackingState.isMediaPlaying` flag accordingly.
    *   **Error Reporting**: Console warnings are logged if expected elements (canvas, play/pause buttons) are not found, informing about skipped tracking.
5.  **Auto-execution**: The entire script runs inside an IIFE, and `initializeTracking()` is called either when `DOMContentLoaded` fires or immediately if the DOM is already ready.